Delivery Boy (HOMDEL)

 

Chef has started Home Delivery scheme in one of his restaurants. As the scheme is new, Chef appoints only one employee to deliver food to various locations. The delivery boy who has been appointed is an absent-minded chap. He always forgets to fill fuel in his delivery scooter. So what he does is that whenever Chef sends him for delivery, he goes to the gas station from the restaurant first. He gets his tank filled and then he heads towards his destination. He will do this every single time irrespective of the destination. The delivery boy tries his best to be on time. And to do this, he will choose those paths (from restaurant to gas station AND gas station to destinaion) which cost him the least amount of time. Your task is to tell the Chef how much time can the delivery boy save if he had enough fuel in his scooter i.e. if he went to the destination directly without stopping for fuel (taking the path which costs him least amount of time).

The city has n streets numbered from 0 to n – 1. The restaurant is on street number s, the gas station is on street number g and the food has to be delivered to street d. Note that s, g and d need not be distinct.

 

Input. First line contains a single integer n (1 ≤ n ≤ 250). Then follows an n * n matrix t which is represented in n lines with n space separated integers on each line.

t[i][j(0 ≤ t[i][j] ≤ 105) denotes the time taken to move from the i-th street to j-th street. Obviously, t[i][i] = 0.

Next line contains a single integer m (1 ≤ m ≤ 104), the number of scenarios. The following m lines contain 3 space separated integers sg and d (0 ≤ sg, dn – 1).

 

Output. For each of the m scenarios, output the time taken by the delivery boy to deliver the food and the time he could have saved if he went directly from s to d. Both these values must be on the same line separated by a single space.

 

Sample input

Sample output

4

0 2 1 3

1 0 4 5

3 1 0 3

1 1 1 0

4

0 2 1

0 2 2

3 1 2

3 0 1

2 0

1 0

3 2

3 2

 

 

РЕШЕНИЕ

графы – алгоритм Флойда-Уоршела

 

Задан взвешенный граф из n вершин. Необходимо ответить на большое число следующих запросов: найдите величину кратчайшего пути из s в d, если при этом следует посетить g. Следует также выяснить, на сколько этот путь будет длиннее кратчайшего пути из s в d, если двигаться напрямую.

 

Анализ алгоритма

Запустим на графе gr алгоритм Флойда – Уоршела для поиска кратчайших путей между всеми парами вершин. Тогда длина кратчайшего пути из s в d с посещением g составит gr[s][g] + gr[g][d]. Длина непосредственно кратчайшего пути из s в d равна gr[s][d].

 

Реализация алгоритма

 

#include <stdio.h>

#include <string.h>

#define MAX 251

int n, i, j, q, s, g, d;

int gr[MAX][MAX];

 

void floyd(void)

{

  int i, j, k;

  for (k = 0; k < n; k++)

  for (i = 0; i < n; i++)

  for (j = 0; j < n; j++)

    if (gr[i][k] + gr[k][j] < gr[i][j])

        gr[i][j] = gr[i][k] + gr[k][j];

}

 

int main(void)

{

  scanf("%d", &n);

  for (i = 0; i < n; i++)

  for (j = 0; j < n; j++)

    scanf("%d", &gr[i][j]);

 

  floyd();

 

  scanf("%d", &q);

  while (q--)

  {

    scanf("%d %d %d", &s, &g, &d);

    int t1 = gr[s][g] + gr[g][d];

    int t2 = gr[s][d];

    printf("%d %d\n", t1, t1 - t2);

  }

 

  return 0;

}